【Vue 學習筆記】Pinia 製作購物車


Posted by helena on 2023-08-29

Pinia的好處

Pinia 是由 Vue.js 的團隊成員所開發的全新狀態管理工具,可以說是Vuex的更新版本。把資料放到一個倉庫去集中管理,需要時再去倉庫拿資料,好處是可以不用把資料傳來傳去,專注在開發上。

安裝Pinia

透過 npm init vue@latest 指令安裝,在 main.js 引用 Pinia 的部份已經都寫好了。

以下為自行安裝

npm install pinia
import { createApp } from "vue";
import { createPinia } from "pinia";

import App from "./App.vue";

const app = createApp(App);

app.use(createPinia());

app.mount("#app");

建立購物車

建立 Stores 資料夾

src 下建立 stores 資料夾 ( cart.js )

src

import { defineStore } from 'pinia'
const { VITE_URL, VITE_PATH } = import.meta.env;
const cartStore(自訂) = defineStore('cart(自訂)', {
  state: () => {
    return {
      carts: {},
    }
  },
  getters: {

  },
  actions: {
     getCart() {
        ...
     },
  },
});

export default cartStore;
Pinia 基礎語法
  • state 對應 data
  • getters 對應 computed
  • actions 對應 methods

匯入 pinia

在需要 pinia 裡的 component(cartStore) 的地方,import的方法

import { mapActions, mapState } from 'pinia';
import cartStore from '../../stores/cart';
const { VITE_URL, VITE_PATH } = import.meta.env;
export default{
// 在 computed 引入 stores 裡的 state 或 getters
  computed:{
    ...mapState(cartStore(自訂), ['carts'])
  },
// 在 methodsd 引入 stores 裡的 actions
  methods:{
    ...mapActions(cartStore(自訂), ['getCart']),
  },
// import 進來的函式與變數可以直接使用
  mounted(){
    this.getCart()
  }
}

以上是 getCart()(取得購物車列表)的方法,同樣適用在新增購物車及刪除購物車,只要在 cart.js 裡的 actions 新增方法,在任何需要 pinia 裡的 component 的地方,使用以上 import 方法即可實現功能。

收藏購物車裡的產品

src 下建立 stores 資料夾 ( favorite.js )

src

import { defineStore } from 'pinia'
import { Toast } from '../../src/methods/swalToast';
const favoritesStore(自訂) = defineStore('favoritesStore(自訂)', {
  state: () => {
  //加載用戶收藏列表的數據,存在本地端,如果沒有的話會是空值 []
  //JSON.parse 將資料由 JSON 格式字串轉回原本的資料內容及型別
  //getItem 讀取 Storage
    return {
      favoritesList(自訂):JSON.parse(localStorage.getItem('favoritesList')) || []
    }
  },
  actions: {
  //用戶點擊時,收藏狀態
    toggleFavorite(product) {
      //通過 findIndex 方法找 product 在 favoritesList 中的索引,如果找不到,則加入收藏,反之取消收藏。
      const favoriteIndex = this.favoritesList.findIndex((item) => item.id === product.id)
      if (favoriteIndex === -1) {
        this.favoritesList.push(product)
        Toast.fire({
          icon: 'success',
          title: '加入收藏'
        })
      } else {
        this.favoritesList.splice(favoriteIndex, 1)
        Toast.fire({
          icon: 'success',
          title: '取消收藏'
        })
      }
    },
  },
  getters: {
  //用解構的方式,從本地儲存狀態中取得資料
    getFavoritesNum(自訂): ({ favoritesList }) => {
      return favoritesList.length
    }
  },
  //深度監聽內部屬性或元素發生的變化
  deep: ['favoritesList']
})
export default favoritesStore

匯入 pinia

在需要 pinia 裡的 component(favoritesStore) 的地方,import的方法

import { mapState, mapActions } from 'pinia';
import favoritesStore from '../../stores/favorite';
export default {
// 在 computed 引入 stores 裡的 state 或 getters
  computed:{
    ...mapState(favoritesStore,['favoritesList','getFavoritesNum']),
  },
  //監聽數據的變化
  watch: {
    favoritesList(自訂): {
    //handler() 將新的 favoritesList 資料,以 JSON 形式保存到本地端,以便下次再進入這個頁面時,保留收藏列表的數據
    //JSON.stringify 將資料轉為 JSON 格式的字串
    //setItem 更新 Storage
      handler() {
        localStorage.setItem('favoritesList', JSON.stringify(this.favoritesList))
      },
      //深度監聽: favoritesList 發生變化時,觸發 handler()
      deep: true
    }
  },
  // 在 methodsd 引入 stores 裡的 actions
  methods: {
    ...mapActions(favoritesStore,['toggleFavorite']),
  },
}

附上購物車及收藏列表的原始碼:
cart
favorite


#pinia #Vue #JSON







Related Posts

DAY25:Detect Pangram

DAY25:Detect Pangram

簡明程式解題入門 - 字串篇 I

簡明程式解題入門 - 字串篇 I

W19_產品開發流程_學習筆記

W19_產品開發流程_學習筆記


Comments